
#pragma once
#include <functional>
#include "common.h"
#include <memory>

class Connection {
 public:
  enum State {
    Invalid = 0,
    Connecting,
    Connected,
    Closed,
  };
  DISALLOW_COPY_AND_MOVE(Connection);
  /**
   * @brief Connection构造函数，构造时即把 fd 注册到 loop 含有到 epoll 中 ， 初始为非阻塞可读事件
   * @param fd 客户端fd
   * @param loop epoll事件池
   */
  Connection(int fd, EventLoop *loop);
  ~Connection();

  void set_delete_connection(std::function<void(int)> const &fn);
  void set_on_connect(std::function<void(Connection *)> const &fn);
  void set_on_recv(std::function<void(Connection *)> const &fn);
  State state() const;
  Socket *socket() const;
  void set_send_buf(const char *str);
  Buffer *read_buf();
  Buffer *send_buf();

  RC Read();
  RC Write();
  RC Send(std::string msg);

  void Close();

  void onConnect(std::function<void()> fn);
  void onMessage(std::function<void()> fn);

 private:
  void Business();
  RC ReadNonBlocking();
  RC WriteNonBlocking();
  RC ReadBlocking();
  RC WriteBlocking();

 private:
  std::unique_ptr<Socket> m_socket;
  std::unique_ptr<Channel> m_channel;

  State m_state;
  std::unique_ptr<Buffer> m_read_buf;
  std::unique_ptr<Buffer> m_send_buf;

  std::function<void(int)> m_delete_connectioin_cb;
  std::function<void(Connection *)> m_on_recv_cb;
};
